package com.lx.errorHanding.listener;

import com.lx.errorHanding.retry.CustomRetryableException;
import com.lx.errorHanding.retry.RetryItemProcessor;
import com.lx.errorHanding.retry.RetryItemWrite;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepScope;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.support.ListItemReader;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.ArrayList;
import java.util.Map;

/**
 * 错误跳过 监听器
 * @author lixing
 * @date 2021/7/13 14:16
 */
@Configuration
public class SkipListenerDemoJobConfigration {
    @Autowired
    private JobBuilderFactory jobBuilderFactory;

    @Autowired
    private StepBuilderFactory stepBuilderFactory;

    @Autowired
    private RetryItemProcessor retryItemProcessor;

    @Autowired
    private RetryItemWrite retryItemWrite;

    @Bean
    public Job retryDemoJob(){
        return jobBuilderFactory.get("retryDemoJob")
                .start(retryDemoStep())
                .build();
    }

    @Bean
    public Step retryDemoStep() {
        return stepBuilderFactory.get("retryDemoStep")
                .<String,String>chunk(10)
                .reader(reader())
                .processor(retryItemProcessor)
                .writer(retryItemWrite)
                .faultTolerant()//设置机制(容错)
                .skip(CustomRetryableException.class)//跳过这次异常
                .skipLimit(10)//一共跳过10次
                .listener(new Mylistener())//监听器
                .build();
    }

    @Bean
    @StepScope
    public ItemReader<? extends String> reader() {
        ArrayList<String> list = new ArrayList<>();
        for (int i =0;i<50;i++){
            list.add(String.valueOf(i));
        }
        ListItemReader reader = new ListItemReader(list);
        return reader;
    }

    @Bean
    @StepScope
    public Tasklet errorHandingOverviewTasklet() {
        return new Tasklet() {
            @Override
            public RepeatStatus execute(StepContribution stepContribution, ChunkContext chunkContext) throws Exception {
                Map<String, Object> stepExecutionContext = chunkContext.getStepContext().getStepExecutionContext();

                if (stepExecutionContext.containsKey("first")){
                    System.out.println("Second run will success ...");
                    return RepeatStatus.FINISHED;
                }else {
                    System.out.println("First run will fail ...");
                    ExecutionContext executionContext = chunkContext.getStepContext().getStepExecution().getExecutionContext();
                    executionContext.put("first",true);
                    throw new RuntimeException("Error occurs...");
                }
            }
        };
    }

}
